<?php


namespace app\app\controller\im;

use app\model\GroupMembersModel;
use app\model\MessageModel;
use app\model\UserModel;
use GatewayClient\Gateway;
use support\Request;
use think\facade\Cache;

Gateway::$registerAddress = '127.0.0.1:1237';

class Core
{
    protected $user_id = 0;

    public function beforeAction(Request $request){
        $this->user_id = $request->user_id;
    }

    public function bind(){
        $userModel = new UserModel();
        $messageModel = new MessageModel();
        $client_id = input('client_id');
        $platform = input('platform');

        $_user = $userModel->where(['user_id' => $this->user_id])->find();

        if($platform=='app' && $_user->app_online_status=='online'){
            $_app_client_id = Cache::get(strval($this->user_id).'_app_client_id');
            if($_app_client_id){
                Gateway::sendToClient($_app_client_id,json_encode(['message_type' => 'quit']));
            }
        }

        Gateway::bindUid($client_id, $this->user_id);
        Cache::tag('im')->set($client_id,strval($this->user_id));

        $group_id_array = GroupMembersModel::where(['uid' => $this->user_id])->column('gid');
        if ($group_id_array) {
            foreach ($group_id_array as $gid) {
                Gateway::joinGroup($client_id, $gid);
            }
        }

        $_user_client_lst = Cache::get(strval($this->user_id));
        if($_user_client_lst){
            array_push($_user_client_lst,$client_id);
            $_user_client_lst = array_values(array_unique($_user_client_lst));
            Cache::tag('im')->set(strval($this->user_id),$_user_client_lst);
        }
        else{
            Cache::tag('im')->set(strval($this->user_id),[$client_id]);
        }
        if($platform=='app'){
            Cache::tag('im')->set(strval($this->user_id).'_app_client_id',$client_id);
            $userModel->where(['user_id' => $this->user_id])->update(['online_status'=>'online','app_online_status'=>'online']);
        }
        else{
            $userModel->where(['user_id' => $this->user_id])->update(['online_status'=>'online']);
        }



        $unread_notice_count = 0;
        // 这个用户没有退出时间
        if ($_user) {
            $logout_timestamp = $_user['logout_timestamp'];
            $notice_read_timestamp = $_user['notice_read_timestamp'];
            $groups = $group_id_array ? "'" . implode("','", $group_id_array) . "'" : -1;
            // 用户有退出时间，则查询message数据库，找出这个用户的所有时间大于$logout_timestamp的消息，这些消息是离线消息
            $unread_message = $messageModel->where("(`to` = :to OR `to` in ($groups)) AND timestamp> $logout_timestamp")
                ->bind(['to' => $this->user_id])
                ->limit(500)->column('data');
            // 读取完毕后更新logout_timestamp，避免多页面时重复提示离线消息
            $userModel->where(['user_id' => $this->user_id])->update(['logout_timestamp'=>time()]);
        }
        if (empty($unread_message)) {
            $unread_message = array();
        }
        // 通知所有客户端当前用户上线
//        $online_message = array(
//            'message_type' => 'online',
//            'id' => $this->user_id
//        );
//        Gateway::sendToAll(json_encode($online_message));
        $rtn_data = [
            'unread_message'=>$unread_message,
            'unread_message_count'=>count($unread_message)
        ];
        return success($rtn_data,0,'登录成功');
    }

    public function sendMsg(){
        $messageModel = new MessageModel();

        $data = input("data");
        $data = $data ?? json_decode(input("json_data"),true);
        $from = $this->user_id;
        $to = $data['to']['id'];
        $type = $data['to']['type'];

        $message_data = [
            'name' => $type === 'friend' ? $data['mine']['name'] : $data['to']['name'],
            'realname' => $type === 'friend' ? $data['mine']['realname'] : $data['to']['realname'],
            'avatar' => $type === 'friend' ? $data['mine']['avatar'] : $data['to']['avatar'],
            'id' => $type === 'friend' ? $from : $to,
            'type' => $type,
            'content' => htmlspecialchars($data['mine']['content']),
            'timestamp' => time() * 1000,
            'from_id' => $from,
            'from_name' => $data['mine']['name'],
            'from_avatar' => $data['mine']['avatar']
        ];

        $chat_message = array(
            'message_type' => 'chatMessage',
            'data' => $message_data
        );

//        //离线推送添加位置

        switch ($type) {
            // 私聊
            case 'friend':
                Gateway::sendToUid($to, json_encode($chat_message));
                break;
            // 群聊
            case 'group':
                Gateway::sendToGroup($to, json_encode($chat_message), Gateway::getClientIdByUid($this->user_id));
                break;
        }

        // 记录消息到message表
        $res = $messageModel->insert(array(
            'from' => $from,
            'to' => $to,
            'data' => json_encode($message_data),
            'timestamp' => time(),
            'type' => $type
        ));
        return $res ? success(null,0,"发送成功") : error(1,"发送失败");
    }

    public function msgAcceptCallBack(){
        $userModel = new UserModel();
        $userModel->where(['user_id' => $this->user_id])->update(['logout_timestamp'=>time()]);
        return success();
    }

}